<!DOCTYPE html>
<head>
    <title>Task Manager</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0 user-scalable=no">
    <link rel="stylesheet" href="../../script/semantic/semantic.min.css">
    <script type="text/javascript" src="../../script/jquery.min.js"></script>
    <script type="text/javascript" src="../../script/semantic/semantic.min.js"></script>
    <script type="text/javascript" src="../../script/ao_module.js"></script>
    <script type="text/javascript" src="../info/js/chart/Chart.min.js"></script>
    <script type="text/javascript" src="../../script/applocale.js"></script>
</head>

<body>
    <br>
    <div class="ui container">
        <div id="cpuChartContainer" style="position: relative;">
            <h2 class="ui header">
                <span locale="taskManager/cpu">CPU</span>
                <div class="sub header" locale="taskManager/cpu_description">CPU Usage (%) in the previous 60 seconds</div>
            </h2>
            <p id="CPUname" style="position: absolute; top: 1em; right: 0.3em; font-size: 16px;" locale="taskManager/cpu_info">Generic Processor</p>
            <canvas id="cpuChart" width="1200" height="300"></canvas>
            <div class="ui stackable grid">
                <div class="four wide column">
                    <div class="ui header">
                        <span id="cpuUsage">0%</span>
                        <div class="sub header" locale="taskManager/cpu_usage_description">Usage</div>
                    </div>
                </div>
                <div class="four wide column">
                    <div class="ui header">
                        <span id="cpufreq">Loading</span>
                        <div class="sub header" locale="taskManager/cpu_frequency_description">Frequency</div>
                    </div>
                </div>
            </div>
        </div>
        <br>
        <div id="ramChartContainer" style="position: relative;">
            <h2 class="ui header">
                <span locale="taskManager/memory">Memory</span>
                <div class="sub header" locale="taskManager/memory_description">RAM Usage</div>
            </h2>
            <p id="RAMInfo" style="position: absolute; top: 1em; right: 0.3em; font-size: 16px;" locale="taskManager/memory_info"></p>
            <canvas id="ramChart" width="1200" height="300"></canvas>
            <br>
            <div class="ui stackable grid">
                <div class="four wide column">
                    <div class="ui header">
                        <span id="ramUsed">Loading</span>
                        <div class="sub header" locale="taskManager/ram_used_description">Used</div>
                    </div>
                </div>
                <div class="four wide column">
                    <div class="ui header">
                        <span id="ramUsedPercentage">Loading</span>
                        <div class="sub header" locale="taskManager/ram_used_percentage_description">Used (%)</div>
                    </div>
                </div>
                <div class="four wide column">
                    <div class="ui header">
                        <span id="ramTotal">Loading</span>
                        <div class="sub header" locale="taskManager/ram_total_description">Total</div>
                    </div>
                </div>
            </div>
        </div>
        <div id="netChartContainer" style="position: relative; margin-top: 1.2em;">
            <h2 class="ui header">
                <span locale="taskManager/network">Network</span>
                <div class="sub header" locale="taskManager/network_description">Network usage in the previous 60 seconds</div>
            </h2>
            <p id="netGraphScale" style="position: absolute; top: 1em; right: 0.3em; font-size: 16px;" locale="taskManager/network_scale">100 kbps</p>
            <canvas id="netChart" width="1200" height="300"></canvas>
            <div class="ui stackable grid">
                <div class="four wide column">
                    <div class="ui header" style="border-left: 2px solid #bc793f; padding-left: 1em;">
                        <span id="rx">Loading</span>
                        <div class="sub header" locale="taskManager/network_received_description">Received</div>
                    </div>
                </div>
                <div class="four wide column">
                    <div class="ui header" style="border-left: 2px dotted #bc793f; padding-left: 1em;">
                        <span id="tx">Loading</span>
                        <div class="sub header" locale="taskManager/network_transmitted_description">Transmitted</div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    

        <br><br>
    </div>
    <script>
        var cpuChart;
        var ramChart;
        var netChart;
        var previousNetData = [0, 0];

        var performanceLocale = NewAppLocale();
        performanceLocale.init("../locale/system_settings/spec.json", function(){
            performanceLocale.translate();
            initInfo();
        });


        //Override Chart.js v3 poor API designs
        Chart.defaults.plugins.tooltip.enabled = false;
        Chart.defaults.plugins.legend.display = false;

        var options = {
            maintainAspectRatio: true,
            responsive: true,
			spanGaps: false,
			elements: {
				line: {
					tension: 0.000001
				}
			},
			plugins: {
				filler: {
					propagate: false
				},
			},
			scales: {
				x: {
                    grid: {
                        color:  "rgba(83, 160, 205, 0.2)"
                    }
                },
                y: {
                    min: 0,
                    max: 100,
                    grid: {
                        color:  "rgba(83, 160, 205, 0.2)"
                    },
                    ticks: {
                        display: false,
                    }
                }
            },
            legend: {
                display: false,
            },
            tooltips: {
                callbacks: {
                    label: function(tooltipItem) {
                            return tooltipItem.yLabel;
                    }
                }
            }
        };

        var ramOptions = {
            maintainAspectRatio: true,
            responsive: true,
			spanGaps: false,
			elements: {
				line: {
					tension: 0.000001
				}
			},
			plugins: {
				filler: {
					propagate: false
				},
			},
			scales: {
				x: {
                    grid: {
                        color:  "rgba(156, 55, 185, 0.2)"
                    }
                },
                y: {
                    min: 0,
                    max: 100,
                    grid: {
                        color:  "rgba(156, 55, 185, 0.2)"
                    },
                    ticks: {
                        display: false,
                    }
                }
            },
            legend: {
                display: false,
            },
            tooltips: {
                callbacks: {
                    label: function(tooltipItem) {
                            return tooltipItem.yLabel;
                    }
                }
            }
        };

        var netOptions = {
            maintainAspectRatio: true,
            responsive: true,
			spanGaps: false,
			elements: {
				line: {
					tension: 0.000001
				}
			},
			plugins: {
				filler: {
					propagate: false
				},
			},
			scales: {
				x: {
                    grid: {
                        color:  "rgba(167, 79, 1, 0.2)"
                    }
                },
                y: {
                    min: Math.min.apply(this, getMergedRxTxDataset()),
                    max: Math.max.apply(this, getMergedRxTxDataset()) + 5,
                    grid: {
                        color:  "rgba(167, 79, 1, 0.2)"
                    },
                    ticks: {
                        display: false,
                    }
                }
            },
            legend: {
                display: false,
            },
            tooltips: {
                callbacks: {
                    label: function(tooltipItem) {
                            return tooltipItem.yLabel;
                    }
                }
            }
        };
        
        chartInit();

        //Special code to handle embedding into the System Setting embedded windows
        var insideIframe = false;
        if (parent.managerInIframe !== undefined && parent.managerInIframe == true){
            $(window).on("click", function(e){
                parent.ao_module_focus();
            });
        }

        function initInfo(){
            $.get("../../system/info/getCPUinfo", function(data){
                var data = JSON.parse(data);
                console.log(data);
                $("#CPUname").text(data.Model);
                if (parseFloat(data.Freq) > 1000){
                    $("#cpufreq").text((data.Freq/1000).toFixed(2) + " Ghz");
                }else{
                    $("#cpufreq").text(data.Freq + " Mhz");
                }
                
            });

            $.get("../../system/info/getRAMinfo", function(data){
                //Return ram in byte
                var ramsize = bytesToSize(data);
                $("#RAMInfo").text(ramsize);
            })
        }

        function bytesToSize(bytes) {
            var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
            if (bytes == 0) return '0 Byte';
            var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
            return (bytes / Math.pow(1024, i)).toFixed(1) + ' ' + sizes[i];
        }

        function bitToSize(bytes) {
            var sizes = ['b', 'Kb', 'Mb', 'Gb', 'Tb'];
            if (bytes == 0) return '0 b';
            var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1000)));
            return (bytes / Math.pow(1024, i)).toFixed(1) + ' ' + sizes[i];
        }


        function chartInit(){
            cpuChart = new Chart('cpuChart', {
				type: 'line',
				data: {
					labels: [],
					datasets: [{
						backgroundColor: "rgba(241,246,250,0.4)",
						borderColor: "#4c9dcb",
						data: [],
                        radius: 0,
                        borderWidth: 2,
						fill: 'start'
                    }]
				},
				options: options
            });
            
            //Push 60 empty data into the chart
            for (var i =0; i < 60; i++){
                addData(cpuChart, "",0)
            }

            //Create RAM Chart
            ramChart = new Chart('ramChart', {
				type: 'line',
				data: {
					labels: [],
					datasets: [{
						backgroundColor: "rgba(244,242,244,0.4)",
						borderColor: "#9528b4",
						data: [],
                        radius: 0,
                        borderWidth: 2,
						fill: 'start'
                    }]
				},
				options: ramOptions
            });

            for (var i =0; i < 60; i++){
                addData(ramChart, "",0)
            }

            //Create Network Chart
            netChart = new Chart('netChart', {
				type: 'line',
				data: {
					labels: [],
					datasets: [{
						backgroundColor: "rgba(252,243,235,0.4)",
						borderColor: "#a74f01",
						data: [],
                        radius: 0,
                        borderWidth: 2,
						fill: 'start'
                    },
                    {
						backgroundColor: "rgba(252,243,235,0.2)",
						borderColor: "#a74f01",
                        borderDash: [3, 3],
						data: [],
                        radius: 0,
                        borderWidth: 2,
						fill: 'start'
                        
                    }]
				},
				options: netOptions
            });

            for (var i =0; i < 60; i++){
                addNetData(netChart, "", 0, 0)
            }
            
        }

        resizeCharts();
        $(window).on("resize", function(){
            resizeCharts();
        })

        function resizeCharts(){
            $("#cpuChart").width($("#cpuChartContainer").width());
            $("#ramChart").width($("#ramChartContainer").width());
        }

        updateData();
        function updateData(){
            //Testing use 
            /*
            setInterval(function(){
                addAndShiftChartDate(cpuChart, "", Math.floor(Math.random() * 50) + 20)
                addAndShiftChartDate(ramChart, "", Math.floor(Math.random() * 10) + 30)
            }, 1000)
            */

             //Calculate the bandwidth diff
            $.get("../../system/network/getNICUsage", function(data){
                if (data.error !== undefined){
                    //Error
                    console.log(data.error);
                    $("#netGraphScale").text(data.error);
                    return;
                }
                if (previousNetData[0] == 0 && previousNetData[1] == 0){
                    //Not initiated. Set base and wait for next iteration
                    previousNetData = [data.RX, data.TX];
                }else{
                    var rxd = data.RX - previousNetData[0];
                    var txd = data.TX - previousNetData[1];
                    previousNetData = [data.RX, data.TX];
                    addAndShiftNetworkData(netChart, "", rxd, txd);

                    $("#rx").text(bitToSize(rxd)+"/s");
                    $("#tx").text(bitToSize(txd)+"/s");

                    //Get the max value of the diagram, round it to the cloest 10x
                    var chartMaxValue = Math.max.apply(this, getMergedRxTxDataset()) * 1.2;

                    //Special Rounding for calculating graph scale
                    baseValue = parseInt(chartMaxValue);
                    var scale = "0 bps"
                    var sizes = ['b', 'Kb', 'Mb', 'Gb', 'Tb', 'Pb'];
                    function roundUpNearest(num) {
                        return Math.ceil(num / 10) * 10;
                    }

                    if (baseValue == 0){

                    }else{
                        var i = parseInt(Math.floor(Math.log(baseValue) / Math.log(1000)));
                        scale = roundUpNearest((baseValue / Math.pow(1024, i)).toFixed(0))
                        scale += ' ' + sizes[i] + "ps";
                    }
                    
                    //console.log(baseValue, chartMaxValue, scale);
                    $("#netGraphScale").text(scale);
                }
            })

            //Get UsageInfo with timeout
            $.ajax({
                url: "../../system/info/getUsageInfo",
                method: "GET",
                success:function(data){
                    //Update graph
                    addAndShiftChartDate(cpuChart, "", data.CPU);
                    addAndShiftChartDate(ramChart, "", data.RamUsage);

                    //Update values
                    $("#cpuUsage").text(data.CPU.toFixed(1) + "%");
                    $("#ramUsedPercentage").text(data.RamUsage.toFixed(1) + "%")
                    $("#ramUsed").text(data.UsedRAM);
                    $("#ramTotal").text(data.TotalRam);

                    setTimeout(function(){
                        updateData();
                    }, 100);
                },
                error: function(){
                    //Error, retry in 5 seconds
                    setTimeout(function(){
                        updateData();
                    }, 5000);
                },
                timeout: 2000
            });
        }

        function addNetData(chart, label, rx, tx) {
            chart.data.labels.push(label);
            chart.data.datasets[0].data.push(rx);
            chart.data.datasets[1].data.push(tx);
            chart.update();
        }

        function addData(chart, label, data) {
            chart.data.labels.push(label);
            chart.data.datasets.forEach((dataset) => {
                dataset.data.push(data);
            });
            chart.update();
        }

        function addAndShiftChartDate(chart, label, newdata) {
            chart.data.labels.splice(0, 1); // remove first label
            chart.data.datasets.forEach(function(dataset) {
                dataset.data.splice(0, 1); // remove first data point
            });

            chart.update();

            // Add new data
            chart.data.labels.push(label); // add new label at end
            chart.data.datasets.forEach(function(dataset, index) {
                dataset.data.push(newdata); // add new data at end
            });

            chart.update();
        }

        function addAndShiftNetworkData(chart, label, rxd, txd) {
            chart.data.labels.splice(0, 1); // remove first label
            chart.data.datasets.forEach(function(dataset) {
                dataset.data.splice(0, 1); // remove first data point
            });

            chart.update();

            // Add new data
            chart.data.labels.push(label); // add new label at end
            chart.data.datasets[0].data.push(rxd);
            chart.data.datasets[1].data.push(txd);
            
            

            //Update the sacle as well
            netChart.options.scales.y.min = Math.min.apply(this, getMergedRxTxDataset());
            netChart.options.scales.y.max = Math.max.apply(this, getMergedRxTxDataset()) *1.2;

            chart.update();
        }

        function getMergedRxTxDataset(){
            if (netChart == undefined){
                return [0, 100];
            }
            var newArr = [];
            newArr = newArr.concat(netChart.data.datasets[0].data,netChart.data.datasets[1].data);
            return newArr;
        }

    </script>
</body>
</html>